<template>
  <div>
    <div v-if="!multipleCol"><!-- 一行一列模式 -->
      <div class="row justify-center" v-for="(field, idx ) in fieldConfig" :key="idx">
        <div :class="field.class || columnClass" v-if="field.type === 'input'">
          <fieldInput :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'select'">
          <filterSelect :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'autocomplete'">
          <autocomplete :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'date' && !field.range">
          <dateInput :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'date' && !!field.range">
          <dateRangeInput :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'month'">
          <monthinput :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'year'">
          <yearinput :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'datetime'">
          <datetimeInput :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'toggleSelect'">
          <toggleSelect :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class ? field.class : 'col-xs-12 col-sm-10 col-md-10'" v-if="field.type === 'table'">
          <detailTable :field="field" :ref="field.ref" class="q-pb-lg" v-on="$attrs" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'checkbox'">
          <fieldCheckbox :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'radio'">
          <fieldRadio :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'rating'">
          <fieldRating :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'toggle'">
          <fieldToggle :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'region'">
          <regionSelect :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div :class="field.class || 'col-xs-12 col-sm-10 col-md-10'" v-if="field.type === 'richedit'">
          <fieldRichedit :field="field" :ref="field.ref" :class="bottomClass(field)" />
        </div>
        <div class="col-12" v-if="field.type === 'separator'">
          <fieldSep :field="field" :ref="field.ref" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'markup'">
          <myMarkupTable :field="field" :ref="field.ref" />
        </div>
        <div :class="field.fullwidth ? 'col-12' : (field.class || columnClass)" v-if="field.type === 'image'">
          <fieldImage :field="field" :ref="field.ref" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'attach'">
          <fieldAttach :field="field" :ref="field.ref" />
        </div>
        <div :class="field.class || columnClass" v-if="field.type === 'terms'">
          <fieldTerms :field="field" :ref="field.ref" />
        </div>
      </div>
    </div>
    <div v-else ><!-- 一行三列模式 -->
      <div class="row">
        <div :class="!['table', 'separator', 'terms'].includes(field.type) && !field.fullwidth ? columnClass : 'col-12'" class="q-px-md" v-for="(field, idx ) in fieldConfig" :key="idx">
          <fieldInput v-if="field.type === 'input'" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <filterSelect v-if="field.type === 'select'" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <autocomplete v-if="field.type === 'autocomplete'" :field="field" :ref="field.ref" />
          <dateInput v-if="field.type === 'date' && !field.range" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <dateRangeInput v-if="field.type === 'date' && !!field.range" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <monthinput v-if="field.type === 'month'" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <yearinput v-if="field.type === 'year'" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <datetimeInput v-if="field.type === 'datetime'" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <toggleSelect v-if="field.type === 'toggleSelect'" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <detailTable v-if="field.type === 'table'" :field="field" :ref="field.ref" class="q-pb-lg" v-on="$attrs" />
          <fieldCheckbox v-if="field.type === 'checkbox'" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <fieldRadio v-if="field.type === 'radio'" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <fieldRating v-if="field.type === 'rating'" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <fieldToggle v-if="field.type === 'toggle'" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <fieldRichedit v-if="field.type === 'richedit'" :field="field" :ref="field.ref" :class="bottomClass(field)" />
          <fieldSep v-if="field.type === 'separator'" :field="field" :ref="field.ref" />
          <myMarkupTable v-if="field.type === 'markup'" :field="field" :ref="field.ref" />
          <fieldImage v-if="field.type === 'image'" :field="field" :ref="field.ref" />
          <fieldAttach v-if="field.type === 'attach'" :field="field" :ref="field.ref" />
          <fieldTerms v-if="field.type === 'terms'" :field="field" :ref="field.ref" />
        </div>
      </div>
    </div>
  </div>

</template>
<script>
import { defineComponent } from 'vue';
import filterSelect from 'src/components/FilterSelect.vue';
import dateInput from 'src/components/DateInput.vue';
import detailTable from 'src/components/DetailTable.vue';
import monthinput from 'src/components/MonthInput.vue';
import yearinput from 'src/components/YearInput.vue';
import datetimeInput from 'src/components/DatetimeInput.vue';
import toggleSelect from 'src/components/ToggleSelect.vue';
import myMarkupTable from 'src/components/MarkupTable.vue';
import fieldInput from 'src/components/FieldInput.vue';
import fieldCheckbox from 'src/components/FieldCheckbox.vue';
import fieldRadio from 'src/components/FieldRadio.vue';
import fieldRating from 'src/components/FieldRating.vue';
import fieldRichedit from 'src/components/FieldRichedit.vue';
import fieldSep from 'src/components/FieldSeparator.vue';
import autocomplete from 'src/components/Autocomplete.vue';
import dateRangeInput from 'src/components/DateRangeInput.vue';
import fieldToggle from 'src/components/FieldToggle.vue';
import regionSelect from 'src/components/RegionSelect.vue';
import fieldImage from 'src/components/FieldImage.vue';
import fieldAttach from 'src/components/FieldAttach.vue';
import fieldTerms from 'src/components/AdditionalTerms.vue';

export default defineComponent({
  components: {
    filterSelect,
    dateInput,
    detailTable,
    monthinput,
    yearinput,
    datetimeInput,
    toggleSelect,
    myMarkupTable,
    fieldInput,
    fieldCheckbox,
    fieldRadio,
    fieldRating,
    fieldRichedit,
    fieldSep,
    autocomplete,
    dateRangeInput,
    fieldToggle,
    regionSelect,
    fieldImage,
    fieldAttach,
    fieldTerms
  },
  name: 'formInput',
  props: {
    fieldlist: {
      type: Object,
      default: () => {}
    },
    multipleCol: {
      type: Boolean,
      default: false // true-一行显示多个 false-一行显示一个
    },
    columnClass: {
      type: String,
      default: 'col-xs-12 col-sm-6 col-md-4'
    }
  },
  data () {
    return {
      activeRichEdit: ''
    }
  },
  computed: {
    fieldConfig () {
      const fields = {};
      Object.keys(this.fieldlist).forEach(key => {
        if (!this.fieldlist[key].hide) {
          fields[key] = this.fieldlist[key];
          fields[key].name = key;
          if (!fields[key].ref) {
            fields[key].ref = key;
          }
        }
      });
      return fields;
    }
  },
  methods: {
    validateTable () { // 校验表格
      const error = [];
      const keys = Object.keys(this.fieldConfig);
      for (const key of keys) {
        if (this.fieldConfig[key].type === 'table') {
          const component = this.$refs[this.fieldConfig[key].ref];
          if (Object.prototype.toString.call(component) === '[object Array]') {
            for (const com of component) {
              const err = com.validate();
              if (err.result === 'fail') error.push(err.message);
            }
          } else {
            const err = component.validate();
            if (err.result === 'fail') error.push(err.message);
          }
        }
      }
      return error.join(',');
    },
    validateSelect () { // 给所有的select子组件focus，用于检查有效性
      const self = this;
      Object.keys(this.fieldConfig).forEach(key => {
        if (self.fieldConfig[key].type === 'select' && self.fieldConfig[key].rules) {
          const component = self.$refs[self.fieldConfig[key].ref];
          if (Object.prototype.toString.call(component) === '[object Array]') {
            component.forEach(com => {
              // com.$refs.select.focus();
              // com.$refs.select.blur();
              com.$refs.select.validate();
            });
          } else {
            // component.$refs.select.focus();
            // component.$refs.select.blur();
            component.$refs.select.validate();
          }
        }
      });
    },
    validateAll () {
      const self = this;
      Object.keys(this.fieldConfig).forEach(key => {
        if (['select', 'autocomplete', 'toggleSelect'].includes(self.fieldConfig[key].type) && self.fieldConfig[key].rules) {
          const component = self.$refs[self.fieldConfig[key].ref];
          if (Object.prototype.toString.call(component) === '[object Array]') {
            component.forEach(com => {
              com.$refs.select.validate();
            });
          } else {
            component.$refs.select.validate();
          }
        } else if (['input', 'date', 'month', 'year'].includes(self.fieldConfig[key].type) && self.fieldConfig[key].rules) {
          const component = self.$refs[self.fieldConfig[key].ref];
          if (Object.prototype.toString.call(component) === '[object Array]') {
            component.forEach(com => {
              com.$refs.input.validate();
            });
          } else {
            component.$refs.input.validate();
          }
        }
      });
    },
    getFormData () { // 提取表单数据
      return new Promise((resolve, reject) => {
        const formData = {};
        const asyncData = [];
        for (const key in this.fieldConfig) {
          if (this.fieldConfig[key].type === 'select' && typeof this.fieldConfig[key].value === 'object' && this.fieldConfig[key].value) {
            formData[key] = this.fieldConfig[key].value.value;
          } else if (['image', 'attach'].includes(this.fieldConfig[key].type)) {
            const component = this.$refs[this.fieldConfig[key].ref];
            if (Object.prototype.toString.call(component) === '[object Array]') {
              component.forEach(com => {
                asyncData.push(com.submit());
              });
            } else {
              asyncData.push(component.submit());
            }
          } else if (this.fieldConfig[key].type === 'table') {
            const component = this.$refs[this.fieldConfig[key].ref];
            if (Object.prototype.toString.call(component) === '[object Array]') {
              component.forEach(com => {
                if (com.waitUploadImages().length > 0) {
                  asyncData.push(com.updateImages());
                } else {
                  formData[key] = this.fieldConfig[key].value;
                }
              });
            } else {
              if (component.waitUploadImages().length > 0) {
                asyncData.push(component.updateImages());
              } else {
                formData[key] = this.fieldConfig[key].value;
              }
            }
          } else {
            formData[key] = this.fieldConfig[key].value;
          }
        }
        // 对于图片及附件，Promise.all()等待返回结果
        if (asyncData.length > 0) {
          Promise.all(asyncData).then(res => {
            res.forEach(({ name, value }) => {
              formData[name] = value;
            });
            resolve(formData);
          });
        } else {
          resolve(formData);
        }
      });
    },
    bottomClass (field) {
      const ret = Number(!!field.hint) + Number(field.compare && field.compare.value !== null);
      if (ret >= 2) {
        return 'q-mb-lg';
      } else if (ret >= 1) {
        return 'q-mb-sm';
      } else {
        return '';
      }
    }
  }
});
</script>
